use std::collections::HashMap;
use std::fmt;
use bytes::{BufMut, BytesMut};
use log::info;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use serde::de::{DeserializeOwned, MapAccess, Visitor};
use serde::ser::SerializeStruct;
use crate::codec::{RpcCodec, RpcCodecFactory, RpcCodecHeader};
use crate::dto::{RpcData, RpcExtData, RpcHeader};
use crate::error::{to_customer_error, CustomerErrorKind, RpcError, RpcErrorDto};
use crate::{RpcContext, RpcResult};

const SPLIT: &'static str = " ";
const NEWLINE: &'static str = "\r\n";

#[derive(Default)]
pub struct RpcJsonCodec;

impl <T: Serialize + DeserializeOwned> RpcCodecFactory<T> for RpcJsonCodec {
    fn create() -> Box<dyn RpcCodec<T>> {
        Box::new(RpcJsonCodec)
    }
}

impl RpcCodecHeader for RpcJsonCodec {
    fn encode_header(&self, header: &RpcHeader) -> RpcResult<Vec<u8>> {
        let data: String = header.try_into()?;
        Ok(data.into_bytes())
    }

    fn decode_header(&self, data: &Vec<u8>) -> RpcResult<(RpcHeader, Vec<u8>)> {
        let value = String::from_utf8(data.clone())?;
        info!("decode rpc header: {}", value);
        let datas : Vec<&str>= value.split(&format!("{}{}", NEWLINE, NEWLINE)).collect();
        if datas.len() != 2 {
            return Err(RpcError::CustomerError {error_kid: CustomerErrorKind::DataError,
                message: "数据格式错误".to_string()});
        }
        let header_str = datas[0];
        let body = datas[1];
        let lines = header_str.lines().collect::<Vec<_>>();

        if lines.len() < 1 {
            return Err(RpcError::CustomerError {error_kid: CustomerErrorKind::DataError,
                message: "数据格式错误".to_string()});
        }

        let headers = lines[0].split(SPLIT).collect::<Vec<_>>();
        if datas.len() < 1 {
            return Err(RpcError::CustomerError {error_kid: CustomerErrorKind::DataError,
                message: "数据格式错误".to_string()});
        }

        let path = headers[0].to_string();
        let version = headers[1].parse::<i32>()?;
        let status = headers[2].parse::<i32>()?;

        let ext_data_len = lines.len() - 1;
        let mut ext_data : HashMap<String, String> = HashMap::with_capacity(ext_data_len as usize);
        for i in 0..ext_data_len {
            let datas = lines[i+1].split(":").collect::<Vec<_>>();
            let k = datas[0].to_string();
            let v = datas[1].to_string();
            ext_data.insert(k, v);
        }

        let header = RpcHeader {
            path,
            version,
            status,
            ext_data: RpcExtData::new(ext_data),
        };
        Ok((header, body.as_bytes().to_vec()))
    }

    fn encode_data(&self, header: &RpcHeader, data: &Vec<u8>) -> RpcResult<Vec<u8>> {
        let header_bytes = self.encode_header(header)?;
        let split_bytes = format!("{}{}", NEWLINE, NEWLINE).into_bytes();
        let length = header_bytes.len() + data.len() + split_bytes.len();
        let mut result = BytesMut::with_capacity(length + 4);
        result.put_u32(length as u32);
        result.extend(header_bytes);
        result.extend(split_bytes);
        result.extend(data);
        Ok(result.freeze().to_vec())
    }
}

impl <T: Serialize + DeserializeOwned> RpcCodec<T> for RpcJsonCodec {

    fn encode(&self, data: &T) -> RpcResult<Vec<u8>> {
        let mut result = format!("{}{}", NEWLINE, NEWLINE);
        let json = serde_json::to_string::<T>(&data)?;
        result.push_str(&json);
        Ok(json.into_bytes())
    }

    fn decode(&self, data: Vec<u8>) -> RpcResult<T> {
        let json = String::from_utf8(data)?;
        let r = serde_json::from_str(&json);
        match r {
            Ok(r) => { Ok(r) }
            Err(e) => { Err(RpcError::EncodeError(e)) }
        }
    }

    fn encode_rpc_data(&self, data: &RpcData<T>) -> RpcResult<Vec<u8>> {
        let header_bytes = self.encode_header(&data.header)?;
        let data_bytes = self.encode(&data.data)?;
        let split_bytes = format!("{}{}", NEWLINE, NEWLINE).into_bytes();
        let length = header_bytes.len() + data_bytes.len() + split_bytes.len();
        let mut result = BytesMut::with_capacity(length + 4);
        result.put_u32(length as u32);
        result.extend(header_bytes);
        result.extend(split_bytes);
        result.extend(data_bytes);
        Ok(result.freeze().to_vec())
    }
}

impl TryInto<String> for &RpcHeader {
    type Error = RpcError;

    fn try_into(self) -> RpcResult<String> {
        let mut result = String::new();

        // path version status
        result.push_str(&self.path);
        result.push_str(SPLIT);
        result.push_str(&self.version.to_string());
        result.push_str(SPLIT);
        result.push_str(&self.status.to_string());

        // ext data
        for (key, value) in self.ext_data.ext_data_map.iter() {
            result.push_str(NEWLINE);
            result.push_str(&key);
            result.push_str(":");
            result.push_str(&value);

        }

        Ok(result)
    }
}

impl Serialize for RpcError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer
    {
        let rpc_error_dto: RpcErrorDto = RpcErrorDto::from(self);
        let mut rgb = serializer.serialize_struct("RpcErrorDto", 2)?;
        rgb.serialize_field("code", &rpc_error_dto.code)?;
        rgb.serialize_field("message", &rpc_error_dto.message)?;
        rgb.end()
    }
}

impl <'de> Deserialize<'de> for RpcError {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>
    {
        // 定义结构体的字段名
        const FIELDS: &'static [&'static str] = &["code", "message"];

        // 定义一个访问者，该访问者将遍历我们的结构体
        struct RpcErrorVisitor;

        impl<'de> Visitor<'de> for RpcErrorVisitor {
            type Value = RpcError;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a struct RpcError")
            }

            // 反序列化一个映射（如JSON对象）
            fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
            where
                M: MapAccess<'de>,
            {
                let mut code = None;
                let mut message = None;

                // 遍历映射中的键值对
                while let Some(key) = map.next_key()? {
                    match key {
                        "code" => {
                            if code.is_some() {
                                return Err(de::Error::duplicate_field("name"));
                            }
                            code = Some(map.next_value()?);
                        }
                        "message" => {
                            if message.is_some() {
                                return Err(de::Error::duplicate_field("age"));
                            }
                            // 这里我们尝试将值解析为字符串，然后转换为u8
                            message = Some(map.next_value()?);
                        }
                        _ => {
                            // 忽略未知字段
                            let _: de::IgnoredAny = map.next_value()?;
                        }
                    }
                }

                let code = code.ok_or_else(|| de::Error::missing_field("name"))?;
                let message = message.ok_or_else(|| de::Error::missing_field("age"))?;

                Ok(to_customer_error(code, message))
            }
        }

        // 开始反序列化
        deserializer.deserialize_struct("RpcError", FIELDS, RpcErrorVisitor)
    }
}

pub(crate) fn get_current_rpc_codec<T: DeserializeOwned + serde::Serialize>(rpc_content: &RpcContext) ->Option<Box<dyn RpcCodec<T>>> {
    let codec_type = rpc_content.get_current_codec_type();
    if let Some(codec_type) = &codec_type {
        if codec_type == "json" {
            return Some(Box::new(RpcJsonCodec {}))
        }
    }
    None
}


